/*
 * @Author: “ChengNan” 1429323234@qq.com
 * @Date: 2023-05-09 14:02:44
 * @LastEditors: “ChengNan” 1429323234@qq.com
 * @LastEditTime: 2023-05-10 20:59:08
 * @FilePath: 
 * @Description: 地图跟随弹框核心js
 */

import { createApp } from 'vue';
import * as Cesium from 'cesium';

export default class TipWindow {
    constructor(option) {
        console.log("TipWindow option", option, window.viewer);
        if (!(option.id)) {
            throw '缺少参数 id 属性';
        }
        if (!(option.EL)) {
            throw '缺少引入组件 EL 属性';
        }
        if (!(option.tipType)) {
            throw '缺少引入组件 tipType 属性';
        }

        this.id = option.id;
        this.viewer = option.viewer || window.viewer;
        this.tipType = option.tipType;
        this.position = option.position;

        const app = createApp(option.EL, {
            theme: option.theme,
            options: option.options
        });
        const vm = app.mount(document.createElement('div'));
        this.vmInstance = vm;

        this.setPopupTips(this.id);

        // 点击窗口上的关闭按钮
        const closeEvent = () => {
            this.windowClose();
        };
        vm.$el.addEventListener('close', closeEvent);

        // 点击窗口放在最前面
        const clickEvent = () => {
            this.resizeWindow();
        };
        vm.$el.addEventListener('click', clickEvent);

        // 初始化位置
        this.initPosition();

        // 将字符串模板生成的内容添加到DOM上
        this.viewer.cesiumWidget.container.appendChild(vm.$el);

        // 添加场景事件
        this.addPostRender();
    }

    setPopupTips() {
        if (!window.PopupTips) {
            window.PopupTips = {};
        }
        if (!window.PopupTips[this.tipType]) {
            window.PopupTips[this.tipType] = [];
        }

        window.PopupTips[this.tipType].push(this);
    }

    // 初始化位置，消除第一次显示的误差
    initPosition() {
        if (!this.vmInstance.$el || !this.vmInstance.$el.style) return;
        const canvasHeight = this.viewer.scene.canvas.clientHeight;
        const windowPosition = new Cesium.Cartesian2();

        // 使用 computeWorldToWindowCoordinates 替代 wgs84ToWindowCoordinates
        if (Cesium.SceneTransforms.computeWorldToWindowCoordinates) {
            Cesium.SceneTransforms.computeWorldToWindowCoordinates(this.viewer.scene, this.position, windowPosition);
        }

        this.vmInstance.$el.style.bottom = canvasHeight - windowPosition.y + 100 + "px";
        const elWidth = this.vmInstance.$el.offsetWidth;
        this.vmInstance.$el.style.left = windowPosition.x + (elWidth / 2) + "px";
        this.vmInstance.$el.style.zIndex = 1;
    }

    // 添加场景事件
    addPostRender() {
        this.viewer.scene.postRender.addEventListener(this.postRender.bind(this), this);
    }

    // 场景渲染事件 实时更新标签的位置 使其与笛卡尔坐标一致
    postRender() {
        if (!this.vmInstance.$el || !this.vmInstance.$el.style) return;
        const canvasHeight = this.viewer.scene.canvas.clientHeight;
        const windowPosition = new Cesium.Cartesian2();

        // 使用 computeWorldToWindowCoordinates 替代 wgs84ToWindowCoordinates
        if (Cesium.SceneTransforms.computeWorldToWindowCoordinates) {
            Cesium.SceneTransforms.computeWorldToWindowCoordinates(this.viewer.scene, this.position, windowPosition);
        }

        this.vmInstance.$el.style.bottom = canvasHeight - windowPosition.y + 100 + "px";
        const elWidth = this.vmInstance.$el.offsetWidth;
        this.vmInstance.$el.style.left = windowPosition.x - 30 + "px";
    }

    // 关闭
    windowClose() {
        this.vmInstance.$el.remove();
        // 删除PopupTips对应的类
        if (window.PopupTips) {
            for (const type in window.PopupTips) {
                for (let index = window.PopupTips[type].length - 1; index >= 0; index--) {
                    const element = window.PopupTips[type][index];
                    if (element.id === this.id) window.PopupTips[type].splice(index, 1);
                }
            }
        }
        this.viewer.scene.postRender.removeEventListener(this.postRender.bind(this), this); // 移除事件监听
    }

    resizeWindow() {
        if (window.PopupTips) {
            for (const key in window.PopupTips) {
                for (const element of window.PopupTips[key]) {
                    if (element.vmInstance &&
                        element.vmInstance.$el &&
                        element.vmInstance.$el.style) element.vmInstance.$el.style.zIndex = 1;
                }
            }
        }

        if (this.vmInstance &&
            this.vmInstance.$el &&
            this.vmInstance.$el.style) this.vmInstance.$el.style.zIndex = 2;
    }
}